﻿using BCCommon;
using BCData.TMS.Agent.AgentRecord;
using BCData.TMS.Packing.PackingCategoryConfig;
using BCData.TMS.Packing.PackingConfig;
using BCDto.Sim.Admin.Admin;
using BCDto.TMS.Packing.PackingConfigOverwrite;
using BCEntity.Common.EntityNameConst;
using BCEntity.TMS.Packing.PackingConfigOverwrite;
using BCService.Common.Area;
using BCService.TMS.Agent.AgentAreaRecord;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BCService.TMS.Packing.PackingConfigOverwrite
{
    public class PackingConfigOverwriteService : IPackingConfigOverwriteService
    {
        private readonly IRedisService redisService;
        private readonly IZoneService zoneService;
        private readonly IPackingConfigOverwriteData packingConfigOverwriteData;
        private readonly IPackingConfigData packingConfigData;
        private readonly IAgentRecordData agentRecordData;
        private readonly IAgentAreaRecordService agentAreaRecordService;
        private readonly IPackingCategoryConfigData packingCategoryConfigData;
        private readonly string key = string.Format("{0}", EntityNameConst.PackingConfigOverwriteEntity);

        public PackingConfigOverwriteService(IRedisService redisService, 
            IZoneService zoneService, 
            IPackingConfigOverwriteData packingConfigOverwriteData, 
            IPackingConfigData packingConfigData, 
            IAgentRecordData agentRecordData, 
            IAgentAreaRecordService agentAreaRecordService,
            IPackingCategoryConfigData packingCategoryConfigData)
        {
            this.redisService = redisService;
            this.zoneService = zoneService;
            this.packingConfigOverwriteData = packingConfigOverwriteData;
            this.packingConfigData = packingConfigData;
            this.agentRecordData = agentRecordData;
            this.agentAreaRecordService = agentAreaRecordService;
            this.packingCategoryConfigData = packingCategoryConfigData;
        }

        public PackingConfigOverwriteDto Add(AdminDto admin, PackingConfigOverwriteRequestDto requestDto)
        {
            if (admin.AgentRecord == null)
            {
                throw new ArgumentException("只有代理商才可重写包装材料配置");
            }
            if (string.IsNullOrWhiteSpace(requestDto.ProvinceCode) && string.IsNullOrWhiteSpace(requestDto.CityCode) && string.IsNullOrWhiteSpace(requestDto.CountyCode))
            {
                throw new ArgumentException("省市区信息不能为空");
            }
            var zoneEntity = this.zoneService.GetFromZoneEntity(requestDto.CountyCode);
            if (zoneEntity == null || zoneEntity.countyEntity == null)
            {
                throw new ArgumentException("区县编码不存在!");
            }
            if (!this.agentAreaRecordService.CheckCountyAuthorize(zoneEntity.countyEntity.CountyCode, admin.AgentRecord.AgentRecordId))
            {
                throw new ArgumentException("此区域授权失败!");
            }
            var packingConfig = this.packingConfigData.GetEntity(requestDto.PackingConfigId).Result;
            if (packingConfig == null)
            {
                throw new ArgumentException("包装材料配置信息不存在");
            }
            var result = this.packingConfigOverwriteData.GetEntity(admin.AgentRecord.AgentRecordId, requestDto.PackingConfigId, zoneEntity.provinceEntity.ProvinceCode, zoneEntity.cityEntity.CityCode, zoneEntity.countyEntity.CountyCode).Result;
            if (result == null)
            {
                result = this.packingConfigOverwriteData.Insert(new PackingConfigOverwriteEntity()
                {
                    PackingConfigId = packingConfig.PackingConfigId,
                    PackingCategoryConfigId = packingConfig.PackingCategoryConfigId,
                    PackingTitle = packingConfig.PackingTitle,
                    PackingWidth = packingConfig.PackingWidth,
                    PackingLength = packingConfig.PackingLength,
                    PackingHeight = packingConfig.PackingHeight,
                    DimensionUnit = packingConfig.DimensionUnit.ToString(),
                    ShowUnit = packingConfig.ShowUnit.ToString(),
                    TransformRatio = packingConfig.TransformRatio,
                    Price = packingConfig.Price,
                    Enabled = packingConfig.Enabled,
                    ProvinceCode = zoneEntity.provinceEntity.ProvinceCode,
                    CityCode = zoneEntity.cityEntity.CityCode,
                    CountyCode = zoneEntity.countyEntity.CountyCode,
                    AgentRecordId = admin.AgentRecord.AgentRecordId,
                    CreateAdminId = admin.AdminId,
                    CreateAdminName = admin.FullName,
                    CreateTime = DateTime.Now,
                    UpdateTime = DateTime.Now,
                    EditAdminId = admin.AdminId,
                    EditAdminName = admin.FullName
                }).GetAwaiter().GetResult();
                this.redisService.DeleteMultipleKey(key, false);
            }
            return result.As<PackingConfigOverwriteDto>();
        }

        public void Delete(AdminDto admin, int packingConfigOverwriteId)
        {
            if (admin.AgentRecord == null)
            {
                throw new ArgumentException("只有代理商才可删除包装材料配置");
            }
            var result = this.packingConfigOverwriteData.GetEntity(packingConfigOverwriteId).Result;
            if (result == null)
            {
                throw new ArgumentException("包装材料配置重写信息不存在");
            }
            if (result.AgentRecordId != admin.AgentRecord.AgentRecordId)
            {
                throw new ArgumentException("此包装材料配置重写信息不属于您，暂无权限删除");
            }
            this.packingConfigOverwriteData.Delete(result.PackingConfigOverwriteId).GetAwaiter().GetResult();
            this.redisService.DeleteMultipleKey(key, false);
        }

        public PageableList<PackingConfigOverwriteViewDto> Query(long? agentRecordId, int? packingCategoryConfigId, string packingTitle, string provinceCode, string cityCode, string countyCode, bool? enabled, DateTime? createStartDate, DateTime? createEndDate, int pageIndex, int pageSize)
        {
            string cacheKey = this.redisService.GetKey(key, agentRecordId, packingCategoryConfigId, packingTitle, provinceCode, cityCode, countyCode, enabled, createStartDate, createEndDate, pageIndex, pageSize);
            var result = this.redisService.TryGet(cacheKey, () =>
            {
                var (data, dataCount) = this.packingConfigOverwriteData.Query(agentRecordId, packingCategoryConfigId, packingTitle, provinceCode, cityCode, countyCode, enabled, createStartDate, createEndDate, pageIndex, pageSize).Result;
                return new PageableList<PackingConfigOverwriteViewDto>()
                {
                    Count = dataCount,
                    Items = data.As<List<PackingConfigOverwriteViewDto>>(),
                    PageIndex = pageIndex,
                    PageSize = pageSize
                };
            }, TimeSpan.FromDays(30));
            return result;
        }

        public PackingConfigOverwriteDto Update(AdminDto admin, int packingConfigOverwriteId, PackingConfigOverwritePutDto putDto)
        {
            if (admin.AgentRecord == null)
            {
                throw new ArgumentException("只有代理商才可修改包装材料配置");
            }
            var packingCategoryConfig = this.packingCategoryConfigData.GetEntity(putDto.PackingCategoryConfigId).Result;
            if (packingCategoryConfig == null)
            {
                throw new ArgumentException("包装材料分类配置信息不存在");
            }
            var result = this.packingConfigOverwriteData.GetEntity(packingConfigOverwriteId).Result;
            if (result == null)
            {
                throw new ArgumentException("包装材料配置重写信息不存在");
            }
            result.PackingCategoryConfigId = packingCategoryConfig.PackingCategoryConfigId;
            result.PackingTitle = putDto.PackingTitle;
            result.PackingWidth = putDto.PackingWidth;
            result.PackingLength = putDto.PackingLength;
            result.PackingHeight = putDto.PackingHeight;
            result.DimensionUnit = putDto.DimensionUnit.ToString();
            result.ShowUnit = putDto.ShowUnit.ToString();
            result.TransformRatio = putDto.TransformRatio;
            result.Price = putDto.Price;
            result.UpdateTime = DateTime.Now;
            result.EditAdminId = admin.AdminId;
            result.EditAdminName = admin.FullName;
            this.packingConfigOverwriteData.Update(result).GetAwaiter().GetResult();
            this.redisService.DeleteMultipleKey(key, false);
            return result.As<PackingConfigOverwriteDto>();
        }

        public PackingConfigOverwriteDto UpdateEnabled(AdminDto admin, int packingConfigOverwriteId, bool enabled)
        {
            if (admin.AgentRecord == null)
            {
                throw new ArgumentException("只有代理商才可修改包装材料配置");
            }
            var result = this.packingConfigOverwriteData.GetEntity(packingConfigOverwriteId).Result;
            if (result == null)
            {
                throw new ArgumentException("包装材料配置重写信息不存在");
            }
            result.Enabled = enabled;
            result.UpdateTime = DateTime.Now;
            result.EditAdminId = admin.AdminId;
            result.EditAdminName = admin.FullName;
            this.packingConfigOverwriteData.Update(result).GetAwaiter().GetResult();
            this.redisService.DeleteMultipleKey(key, false);
            return result.As<PackingConfigOverwriteDto>();
        }
    }
}
